from dtos.result import Result


class CheckParams(object):

    def __init__(self, params, conditions: list):
        self.params = params
        self.conditions = conditions
        self.result = {}

    def _check_conditions(self):
        if not isinstance(self.conditions, list):
            return False
        for item in self.conditions:
            if not isinstance(item, list) or len(item) not in (3, 4):
                return False
        return True

    def _check_type(self):
        _check_params = False if not isinstance(self.params, dict) else True
        _check_conditions = self._check_conditions()
        _all = _check_params & _check_conditions
        if not _all:
            return Result.error_result(message="handler中参数校验方法配置错误")
        return Result.success_result()

    def _check_required(self, is_required, v, param, default_v=None):
        if is_required and (not v and v != 0):
            return Result.error_result(message="参数%s不能为空" % str(param))
        self.result[param] = default_v if (not v and v != 0) else v
        return Result.success_result()

    @staticmethod
    def check_param_verify_func(func_list, v):
        if not isinstance(func_list, list):
            return Result.error_result(message="handler中，对于参数函数校验的配置错误")
        for _func_info in func_list:
            if not isinstance(_func_info, list):
                return Result.error_result(message="handler中，对于参数函数校验的info配置错误")
            _func, _param = _func_info[0], None if len(_func_info) == 1 else _func_info[1]
            if _param and isinstance(_param, list):
                _param.insert(0, v)
            else:
                _param = [v]
            _func_res = _func(*_param)
            if not _func_res.is_success:
                return _func_res
        return Result.success_result()

    def _check_params(self):
        for condition in self.conditions:
            param, is_required, default_v = condition[0], condition[1], condition[2]
            v = self.params.get(param, None)
            _check_required_res = self._check_required(is_required, v, param, default_v)
            if not _check_required_res.is_success:
                return _check_required_res
            if len(condition) > 3:
                _func_res = self.check_param_verify_func(condition[3], v)
                if not _func_res.is_success:
                    return _func_res
        return Result.success_result()

    def check(self):
        _check_func_list = [
            self._check_type,
            self._check_params
        ]
        for _check_func in _check_func_list:
            _check_res = _check_func()
            if not _check_res.is_success:
                return _check_res
        return Result.success_result(data=self.result)
